package com.dragon.hibernate.dao.impl;

import java.lang.reflect.ParameterizedType;
import java.util.List;

import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.util.Assert;

import com.dragon.hibernate.dao.IBaseDao;

public class BaseDao<E extends java.io.Serializable, PK extends java.io.Serializable> extends Dao implements IBaseDao<E, PK> {

	private static final Logger logger = LogManager.getLogger(BaseDao.class.getName());
	private final Class<E> entityClass;
	
	@SuppressWarnings("unchecked")
	public BaseDao() {
		this.entityClass = (Class<E>) ((ParameterizedType) getClass().getGenericSuperclass()).getActualTypeArguments()[0];
	}

	// @Resource
	public void setSessionFactory(SessionFactory sessionFactory) {
		this.sessionFactory = sessionFactory;
	}

	public Session getSession() {
		// 事务必须是开启的，否则获取不到
		return sessionFactory.getCurrentSession();
	}

	@SuppressWarnings("unchecked")
	@Override
	public E get(PK id) {
		Assert.notNull(id, "id is required");
		return (E) getSession().get(entityClass, id);
	}
	
	

	@SuppressWarnings("unchecked")
	@Override
	public E load(PK id) {
		Assert.notNull(id, "id is required");
		return (E) getSession().load(entityClass, id);
	}
	
	@SuppressWarnings("unchecked")
	@Override
	public List<E> get(PK[] ids) {
		Assert.notEmpty(ids, "ids must not be empty");
		String hql = "from " + entityClass.getName() + " as model where model.id in(:ids)";
		return getSession().createQuery(hql).setParameterList("ids", ids).list();
	}
	
	

	@SuppressWarnings("unchecked")
	@Override
	public E get(String propertyName, Object value) {
		Assert.hasText(propertyName, "propertyName must not be empty");
		Assert.notNull(value, "value is required");
		String hql = "from " + entityClass.getName() + " as model where model." + propertyName + " = ?";
		return (E) getSession().createQuery(hql).setParameter(0, value).uniqueResult();
	}

	@SuppressWarnings("unchecked")
	@Override
	public List<E> getList(String propertyName, Object value) {
		Assert.hasText(propertyName, "propertyName must not be empty");
		Assert.notNull(value, "value is required");
		String hql = "from " + entityClass.getName() + " as model where model." + propertyName + " = ?";
		return getSession().createQuery(hql).setParameter(0, value).list();
	}

	@SuppressWarnings("unchecked")
	@Override
	public List<E> getAll() {
		String hql = "from " + entityClass.getName();
		return getSession().createQuery(hql).list();
	}
	
	@Override
	public boolean isExist(String propertyName, Object value) {
		Assert.hasText(propertyName, "propertyName must not be empty");
		Assert.notNull(value, "value is required");
		E object = get(propertyName, value);
		return (object != null);
	}

	
	/* (non-Javadoc)
	 * @see com.dragon.hibernate.dao.IBaseDao#delete(PK[])
	 */
	@Override
	public void deleteById(PK id) {
		Assert.notNull(id, "id is required");
		E entity = load(id);
		getSession().delete(entity);
	}
	
	
	/**
	 * 根据ID数组删除实体对象.
	 * 
	 * @param ids ID数组
	 * @see com.dragon.hibernate.dao.IBaseDao#delete(PK[])
	 */
	@Override
	public void delete(PK[] ids) {
		Assert.notEmpty(ids, "ids must not be empty");
		for (PK id : ids) {
			E entity = load(id);
			getSession().delete(entity);
		}
	}
	
	

}
